package com.haoxuer.discover.function.controller.rest;


import bsh.EvalError;
import bsh.Interpreter;
import com.haoxuer.discover.function.data.entity.Function;
import com.haoxuer.discover.function.data.service.FunctionService;
import com.haoxuer.discover.rest.base.ResponseObject;
import com.haoxuer.discover.web.controller.front.BaseController;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Scope;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;

@Scope("prototype")
@RestController
public class FunctionRestController extends BaseController implements ApplicationContextAware {

  private ApplicationContext context;

  @Autowired
  private FunctionService functionService;

  @RequestMapping("/function/{key}")
  public ResponseObject function(@PathVariable("key") String key, HttpServletRequest request) {
    ResponseObject result = new ResponseObject();
    Function function = functionService.findByKey(key);
    if (function == null) {
      result.setCode(501);
      result.setMsg("无效key");
      return result;
    }
    if (StringUtils.isEmpty(function.getScript())) {
      result.setCode(502);
      result.setMsg("无效脚本");
      return result;
    }

    Interpreter interpreter = new Interpreter();

    try {
      interpreter.set("request", request);
      interpreter.set("context", context);
      context.getBean("FunctionService");
      StringBuffer buffer = new StringBuffer();
      buffer.append(function.getScript());
      interpreter.eval(buffer.toString());

      Object object = interpreter.get("result");
      if (object != null) {
        if (object instanceof ResponseObject) {
          result = (ResponseObject) object;
        }
      }
    } catch (EvalError evalError) {
      evalError.printStackTrace();
    }

    return result;
  }

  @RequestMapping("/api/{key}")
  public ModelAndView api(@PathVariable("key") String key, HttpServletRequest request) {
    ModelAndView result = new ModelAndView(new MappingJackson2JsonView());
    Function function = functionService.findByKey(key);
    if (function == null) {
      result.addObject("code", 501);
      result.addObject("msg", "无效key");
      return result;
    }
    if (StringUtils.isEmpty(function.getScript())) {
      result.addObject("code", 502);
      result.addObject("msg", "无效脚本");
      return result;
    }

    Interpreter interpreter = new Interpreter();
    try {
      interpreter.set("request", request);
      interpreter.set("context", context);
      interpreter.set("model", result);
      StringBuffer buffer = new StringBuffer();
      buffer.append(function.getScript());
      interpreter.eval(buffer.toString());
    } catch (EvalError evalError) {
      evalError.printStackTrace();
      result.addObject("code", 503);
      result.addObject("msg", "" + evalError.getErrorText());
    }
    return result;
  }

  @RequestMapping("/page/{key}")
  public String page(@PathVariable("key") String key, HttpServletRequest request) {
    String result = "";
    Function function = functionService.findByKey(key);

    Interpreter interpreter = new Interpreter();
    try {
      interpreter.set("request", request);
      interpreter.set("context", context);

      if (function != null && function.getScript() != null) {
        StringBuffer buffer = new StringBuffer();
        buffer.append(function.getScript());
        interpreter.eval(buffer.toString());
      }
      Object object = interpreter.get("result");
      if (object != null) {
        if (object instanceof String) {
          return getView((String) object);
        }
      }
    } catch (EvalError evalError) {
      evalError.printStackTrace();
    }
    return getView("nofound");
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.context = applicationContext;

  }
}
